home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / gdb-4.5 / dist / bfd / bout.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-02  |  22.8 KB  |  769 lines

  1. /* BFD back-end for Intel 960 b.out binaries.
  2.    Copyright (C) 1990-1991 Free Software Foundation, Inc.
  3.    Written by Cygnus Support.
  4.  
  5. This file is part of BFD, the Binary File Descriptor library.
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. /* $Id: bout.c,v 1.28 1992/04/02 07:26:11 gnu Exp $ */
  22.  
  23. #include "bfd.h"
  24. #include "sysdep.h"
  25. #include "libbfd.h"
  26.  
  27. #include "bout.h"
  28.  
  29. #include "aout/stab_gnu.h"
  30. #include "libaout.h"        /* BFD a.out internal data structures */
  31.  
  32. PROTO (static boolean, b_out_squirt_out_relocs,(bfd *abfd, asection *section));
  33. PROTO (static bfd_target *, b_out_callback, (bfd *));
  34.  
  35. PROTO (boolean, aout_32_slurp_symbol_table, (bfd *abfd));
  36. PROTO (void , aout_32_write_syms, ());
  37.  
  38. /* Swaps the information in an executable header taken from a raw byte
  39.    stream memory image, into the internal exec_header structure.  */
  40.  
  41. PROTO(void, bout_swap_exec_header_in,
  42.       (bfd *abfd,
  43.       struct external_exec *raw_bytes,
  44.       struct internal_exec *execp));
  45.      
  46. void
  47. DEFUN(bout_swap_exec_header_in,(abfd, raw_bytes, execp),
  48.       bfd *abfd AND
  49.       struct external_exec *raw_bytes AND
  50.       struct internal_exec *execp)
  51. {
  52.   struct external_exec *bytes = (struct external_exec *)raw_bytes;
  53.  
  54.   /* Now fill in fields in the execp, from the bytes in the raw data.  */
  55.   execp->a_info   = bfd_h_get_32 (abfd, bytes->e_info);
  56.   execp->a_text   = GET_WORD (abfd, bytes->e_text);
  57.   execp->a_data   = GET_WORD (abfd, bytes->e_data);
  58.   execp->a_bss    = GET_WORD (abfd, bytes->e_bss);
  59.   execp->a_syms   = GET_WORD (abfd, bytes->e_syms);
  60.   execp->a_entry  = GET_WORD (abfd, bytes->e_entry);
  61.   execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
  62.   execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
  63.   execp->a_tload  = GET_WORD (abfd, bytes->e_tload);
  64.   execp->a_dload  = GET_WORD (abfd, bytes->e_dload);
  65.   execp->a_talign = bytes->e_talign[0];
  66.   execp->a_dalign = bytes->e_dalign[0];
  67.   execp->a_balign = bytes->e_balign[0];
  68. }
  69.  
  70. /* Swaps the information in an internal exec header structure into the
  71.    supplied buffer ready for writing to disk.  */
  72.  
  73. PROTO(void, bout_swap_exec_header_out,
  74.       (bfd *abfd,
  75.        struct internal_exec *execp,
  76.        struct external_exec *raw_bytes));
  77. void
  78. DEFUN(bout_swap_exec_header_out,(abfd, execp, raw_bytes),
  79.      bfd *abfd AND
  80.      struct internal_exec *execp AND 
  81.      struct external_exec *raw_bytes)
  82. {
  83.   struct external_exec *bytes = (struct external_exec *)raw_bytes;
  84.  
  85.   /* Now fill in fields in the raw data, from the fields in the exec struct. */
  86.   bfd_h_put_32 (abfd, execp->a_info  , bytes->e_info);
  87.   PUT_WORD (abfd, execp->a_text  , bytes->e_text);
  88.   PUT_WORD (abfd, execp->a_data  , bytes->e_data);
  89.   PUT_WORD (abfd, execp->a_bss   , bytes->e_bss);
  90.   PUT_WORD (abfd, execp->a_syms  , bytes->e_syms);
  91.   PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
  92.   PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
  93.   PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
  94.   PUT_WORD (abfd, execp->a_tload , bytes->e_tload);
  95.   PUT_WORD (abfd, execp->a_dload , bytes->e_dload);
  96.   bytes->e_talign[0] = execp->a_talign;
  97.   bytes->e_dalign[0] = execp->a_dalign;
  98.   bytes->e_balign[0] = execp->a_balign;
  99.   bytes->e_unused[0] = 0;        /* Clean structs are godly structs */
  100. }
  101.  
  102.  
  103. static bfd_target *
  104. b_out_object_p (abfd)
  105.      bfd *abfd;
  106. {
  107.   struct internal_exec anexec;
  108.   struct external_exec exec_bytes;
  109.  
  110.   if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
  111.       != EXEC_BYTES_SIZE) {
  112.     bfd_error = wrong_format;
  113.     return 0;
  114.   }
  115.  
  116.   anexec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
  117.  
  118.   if (N_BADMAG (anexec)) {
  119.     bfd_error = wrong_format;
  120.     return 0;
  121.   }
  122.  
  123.   bout_swap_exec_header_in (abfd, &exec_bytes, &anexec);
  124.   return aout_32_some_aout_object_p (abfd, &anexec, b_out_callback);
  125. }
  126.  
  127.  
  128. /* Finish up the opening of a b.out file for reading.  Fill in all the
  129.    fields that are not handled by common code.  */
  130.  
  131. static bfd_target *
  132. b_out_callback (abfd)
  133.      bfd *abfd;
  134. {
  135.   struct internal_exec *execp = exec_hdr (abfd);
  136.   unsigned long bss_start;
  137.  
  138.   /* Architecture and machine type */
  139.   bfd_set_arch_mach(abfd, 
  140.             bfd_arch_i960, /* B.out only used on i960 */
  141.             bfd_mach_i960_core /* Default */
  142.             );
  143.  
  144.   /* The positions of the string table and symbol table.  */
  145.   obj_str_filepos (abfd) = N_STROFF (*execp);
  146.   obj_sym_filepos (abfd) = N_SYMOFF (*execp);
  147.  
  148.   /* The alignments of the sections */
  149.   obj_textsec (abfd)->alignment_power = execp->a_talign;
  150.   obj_datasec (abfd)->alignment_power = execp->a_dalign;
  151.   obj_bsssec  (abfd)->alignment_power = execp->a_balign;
  152.  
  153.   /* The starting addresses of the sections.  */
  154.   obj_textsec (abfd)->vma = execp->a_tload;
  155.   obj_datasec (abfd)->vma = execp->a_dload;
  156.  
  157.   /* And reload the sizes, since the aout module zaps them */
  158.   obj_textsec (abfd)->_raw_size = execp->a_text;
  159.  
  160.   bss_start = execp->a_dload + execp->a_data; /* BSS = end of data section */
  161.   obj_bsssec (abfd)->vma = align_power (bss_start, execp->a_balign);
  162.  
  163.   /* The file positions of the sections */
  164.   obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
  165.   obj_datasec (abfd)->filepos = N_DATOFF(*execp);
  166.  
  167.   /* The file positions of the relocation info */
  168.   obj_textsec (abfd)->rel_filepos = N_TROFF(*execp);
  169.   obj_datasec (abfd)->rel_filepos =  N_DROFF(*execp);
  170.  
  171.   adata(abfd).page_size = 1; /* Not applicable. */
  172.   adata(abfd).segment_size = 1; /* Not applicable. */
  173.   adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE;
  174.  
  175.   return abfd->xvec;
  176. }
  177.  
  178. struct bout_data_struct {
  179.     struct aoutdata a;
  180.     struct internal_exec e;
  181. };
  182.  
  183. static boolean
  184. b_out_mkobject (abfd)
  185.      bfd *abfd;
  186. {
  187.   struct bout_data_struct *rawptr;
  188.  
  189.   rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, sizeof (struct bout_data_struct));
  190.   if (rawptr == NULL) {
  191.       bfd_error = no_memory;
  192.       return false;
  193.     }
  194.  
  195.   abfd->tdata.bout_data = rawptr;
  196.   exec_hdr (abfd) = &rawptr->e;
  197.  
  198.   /* For simplicity's sake we just make all the sections right here. */
  199.   obj_textsec (abfd) = (asection *)NULL;
  200.   obj_datasec (abfd) = (asection *)NULL;
  201.   obj_bsssec (abfd) = (asection *)NULL;
  202.  
  203.   bfd_make_section (abfd, ".text");
  204.   bfd_make_section (abfd, ".data");
  205.   bfd_make_section (abfd, ".bss");
  206.  
  207.   return true;
  208. }
  209.  
  210. static boolean
  211. b_out_write_object_contents (abfd)
  212.      bfd *abfd;
  213. {
  214.   struct external_exec swapped_hdr;
  215.  
  216.   exec_hdr (abfd)->a_info = BMAGIC;
  217.  
  218.   exec_hdr (abfd)->a_text = obj_textsec (abfd)->_raw_size;
  219.   exec_hdr (abfd)->a_data = obj_datasec (abfd)->_raw_size;
  220.   exec_hdr (abfd)->a_bss = obj_bsssec (abfd)->_raw_size;
  221.   exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist);
  222.   exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
  223.   exec_hdr (abfd)->a_trsize = ((obj_textsec (abfd)->reloc_count) *
  224.                                sizeof (struct relocation_info));
  225.   exec_hdr (abfd)->a_drsize = ((obj_datasec (abfd)->reloc_count) *
  226.                                sizeof (struct relocation_info));
  227.  
  228.   exec_hdr (abfd)->a_talign = obj_textsec (abfd)->alignment_power;
  229.   exec_hdr (abfd)->a_dalign = obj_datasec (abfd)->alignment_power;
  230.   exec_hdr (abfd)->a_balign = obj_bsssec (abfd)->alignment_power;
  231.  
  232.   exec_hdr (abfd)->a_tload = obj_textsec (abfd)->vma;
  233.   exec_hdr (abfd)->a_dload = obj_datasec (abfd)->vma;
  234.  
  235.   bout_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr);
  236.  
  237.   bfd_seek (abfd, 0L, SEEK_SET);
  238.   bfd_write ((PTR) &swapped_hdr, 1, EXEC_BYTES_SIZE, abfd);
  239.  
  240.   /* Now write out reloc info, followed by syms and strings */
  241.   if (bfd_get_symcount (abfd) != 0) 
  242.     {
  243.       bfd_seek (abfd,
  244.         (long)(N_SYMOFF(*exec_hdr(abfd))), SEEK_SET);
  245.  
  246.       aout_32_write_syms (abfd);
  247.  
  248.       bfd_seek (abfd,    (long)(N_TROFF(*exec_hdr(abfd))), SEEK_SET);
  249.  
  250.       if (!b_out_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
  251.       bfd_seek (abfd, (long)(N_DROFF(*exec_hdr(abfd))), SEEK_SET);
  252.  
  253.       if (!b_out_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
  254.     }
  255.   return true;
  256. }
  257.  
  258. /** Some reloc hackery */
  259.  
  260. #define CALLS     0x66003800    /* Template for 'calls' instruction    */
  261. #define BAL     0x0b000000    /* Template for 'bal' instruction    */
  262. #define BAL_MASK 0x00ffffff
  263.  
  264. static bfd_reloc_status_type 
  265. callj_callback(abfd, reloc_entry, symbol_in, data, input_section)
  266. bfd *abfd;
  267. arelent *reloc_entry;
  268. asymbol *symbol_in;
  269. PTR data;
  270. asection *input_section;
  271. {
  272.   int  word = bfd_get_32(abfd, (bfd_byte *)data + reloc_entry->address);
  273.   aout_symbol_type  *symbol = aout_symbol(symbol_in);
  274.  
  275.   if (IS_OTHER(symbol->other)) {
  276.     /* Call to a system procedure - replace code with system
  277.        procedure number */
  278.     word = CALLS | (symbol->other - 1);
  279.     bfd_put_32(abfd, word, (bfd_byte *)data + reloc_entry->address); /* rplc */
  280.     return bfd_reloc_ok;
  281.   }
  282.  
  283.   if (IS_CALLNAME(symbol->other)) {
  284.     aout_symbol_type *balsym = symbol+1;
  285.     /* The next symbol should be an N_BALNAME */
  286.     BFD_ASSERT(IS_BALNAME(balsym->other));
  287.  
  288.     /* We are calling a leaf - so replace the call instruction
  289.        with a bal */
  290.   
  291.     word = BAL |
  292.       (((word & BAL_MASK) +
  293.      balsym->symbol.section->output_offset +
  294.      balsym->symbol.section->output_section->vma+
  295.     balsym->symbol.value + reloc_entry->addend - 
  296.     ( input_section->output_section->vma + input_section->output_offset))
  297.        & BAL_MASK);
  298.  
  299.     bfd_put_32(abfd, word, (bfd_byte *) data + reloc_entry->address); /* rplc */
  300.     return bfd_reloc_ok;
  301.   }
  302.   return bfd_reloc_continue;
  303.  
  304. }
  305. /* type rshift size  bitsize      pcrel    bitpos  absolute overflow check*/
  306.  
  307.  
  308. static reloc_howto_type howto_reloc_callj =
  309. HOWTO( 3, 0, 2, 24, true, 0, true, true, callj_callback,"callj", true, 0x00ffffff, 0x00ffffff,false);
  310. static  reloc_howto_type howto_reloc_abs32 =
  311. HOWTO(1, 0, 2, 32, false, 0, true, true,0,"abs32", true, 0xffffffff,0xffffffff,false);
  312. static reloc_howto_type howto_reloc_pcrel24 =
  313. HOWTO(2, 0, 2, 24, true, 0, true, true,0,"pcrel24", true, 0x00ffffff,0x00ffffff,false);
  314.  
  315. /* Allocate enough room for all the reloc entries, plus pointers to them all */
  316.  
  317. static boolean
  318. b_out_slurp_reloc_table (abfd, asect, symbols)
  319.      bfd *abfd;
  320.      sec_ptr asect;
  321.      asymbol **symbols;
  322. {
  323.   register struct relocation_info *rptr;
  324.   unsigned int counter ;
  325.   arelent *cache_ptr ;
  326.   int extern_mask, pcrel_mask, callj_mask;
  327.  
  328.   unsigned int count;
  329.   size_t  reloc_size;
  330.   struct relocation_info *relocs;
  331.   arelent *reloc_cache;
  332.  
  333.   if (asect->relocation) return true;
  334.   if (!aout_32_slurp_symbol_table (abfd)) return false;
  335.  
  336.   if (asect == obj_datasec (abfd)) {
  337.       reloc_size = exec_hdr(abfd)->a_drsize;
  338.       goto doit;
  339.     }
  340.  
  341.   if (asect == obj_textsec (abfd)) {
  342.       reloc_size = exec_hdr(abfd)->a_trsize;
  343.       goto doit;
  344.     }
  345.  
  346.   bfd_error = invalid_operation;
  347.   return false;
  348.  
  349.  doit:
  350.   bfd_seek (abfd, (long)(asect->rel_filepos),  SEEK_SET);
  351.   count = reloc_size / sizeof (struct relocation_info);
  352.  
  353.   relocs = (struct relocation_info *) bfd_xmalloc (reloc_size);
  354.   if (!relocs) {
  355.       bfd_error = no_memory;
  356.       return false;
  357.     }
  358.   reloc_cache = (arelent *) bfd_xmalloc ((count+1) * sizeof (arelent));
  359.   if (!reloc_cache) {
  360.       free ((char*)relocs);
  361.       bfd_error = no_memory;
  362.       return false;
  363.     }
  364.  
  365.   if (bfd_read ((PTR) relocs, 1, reloc_size, abfd) != reloc_size) {
  366.       bfd_error = system_call_error;
  367.       free (reloc_cache);
  368.       free (relocs);
  369.       return false;
  370.     }
  371.  
  372.  
  373.   
  374.   if (abfd->xvec->header_byteorder_big_p) {
  375.       /* big-endian bit field allocation order */
  376.       pcrel_mask  = 0x80;
  377.       extern_mask = 0x10;
  378.       callj_mask  = 0x02;
  379.     } else {
  380.     /* little-endian bit field allocation order */
  381.     pcrel_mask  = 0x01;
  382.     extern_mask = 0x08;
  383.     callj_mask  = 0x40;
  384.       }
  385.  
  386.   for (rptr = relocs, cache_ptr = reloc_cache, counter = 0;
  387.        counter < count;
  388.        counter++, rptr++, cache_ptr++) 
  389.   {
  390.     unsigned char *raw = (unsigned char *)rptr;
  391.     unsigned int symnum;
  392.     cache_ptr->address = bfd_h_get_32 (abfd, raw + 0);
  393.     if (abfd->xvec->header_byteorder_big_p) 
  394.     {
  395.       symnum = (raw[4] << 16) | (raw[5] << 8) | raw[6];
  396.     } 
  397.     else
  398.     {
  399.       symnum = (raw[6] << 16) | (raw[5] << 8) | raw[4];
  400.     }
  401.  
  402.     if (raw[7] & extern_mask) 
  403.     {
  404.     /* if this is set then the r_index is a index into the symbol table;
  405.      * if the bit is not set then r_index contains a section map.
  406.      * we either fill in the sym entry with a pointer to the symbol,
  407.      * or point to the correct section
  408.      */
  409.     cache_ptr->sym_ptr_ptr = symbols + symnum;
  410.     cache_ptr->addend = 0;
  411.       } else 
  412.       {
  413.       /* in a.out symbols are relative to the beginning of the
  414.        * file rather than sections ?
  415.        * (look in translate_from_native_sym_flags)
  416.        * the reloc entry addend has added to it the offset into the
  417.        * file of the data, so subtract the base to make the reloc
  418.        * section relative */
  419.       cache_ptr->sym_ptr_ptr = (asymbol **)NULL;
  420.       switch (symnum) 
  421.       {
  422.         case N_TEXT:
  423.         case N_TEXT | N_EXT:
  424.           cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr;
  425.           cache_ptr->addend = - obj_textsec(abfd)->vma;
  426.           break;
  427.         case N_DATA:
  428.         case N_DATA | N_EXT:
  429.           cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr;
  430.           cache_ptr->addend = - obj_datasec(abfd)->vma;
  431.           break;
  432.         case N_BSS:
  433.         case N_BSS | N_EXT:
  434.           cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr;
  435.           cache_ptr->addend =  - obj_bsssec(abfd)->vma;
  436.           break;
  437.         case N_ABS:
  438.         case N_ABS | N_EXT:
  439.           BFD_ASSERT(0);
  440.           break;
  441.         default:
  442.           BFD_ASSERT(0);
  443.           break;
  444.         }
  445.     
  446.     }
  447.  
  448.     /* the i960 only has a few relocation types:
  449.        abs 32-bit and pcrel 24bit.   except for callj's!  */
  450.     if (raw[7] & callj_mask)
  451.      cache_ptr->howto = &howto_reloc_callj;
  452.     else if ( raw[7] & pcrel_mask)
  453.      cache_ptr->howto = &howto_reloc_pcrel24;
  454.     else
  455.      cache_ptr->howto = &howto_reloc_abs32;
  456.   }
  457.  
  458.  
  459.   free (relocs);
  460.   asect->relocation = reloc_cache;
  461.   asect->reloc_count = count;
  462.  
  463.  
  464.   return true;
  465. }
  466.  
  467.  
  468. static boolean
  469. b_out_squirt_out_relocs (abfd, section)
  470.      bfd *abfd;
  471.      asection *section;
  472. {
  473.  
  474.   arelent **generic;
  475.   int r_extern;
  476.   int r_idx;
  477.   int r_addend;
  478.   
  479.   unsigned int count = section->reloc_count;
  480.   struct relocation_info *native, *natptr;
  481.   size_t natsize = count * sizeof (struct relocation_info);
  482.   int extern_mask, pcrel_mask,  len_2, callj_mask;
  483.   if (count == 0) return true;
  484.   generic   = section->orelocation;
  485.   native = ((struct relocation_info *) bfd_xmalloc (natsize));
  486.   if (!native) {
  487.       bfd_error = no_memory;
  488.       return false;
  489.     }
  490.  
  491.   if (abfd->xvec->header_byteorder_big_p) 
  492.   {
  493.     /* Big-endian bit field allocation order */
  494.     pcrel_mask  = 0x80;
  495.     extern_mask = 0x10;
  496.     len_2       = 0x40;
  497.     callj_mask  = 0x02;
  498.   } 
  499. else 
  500.   {
  501.     /* Little-endian bit field allocation order */
  502.     pcrel_mask  = 0x01;
  503.     extern_mask = 0x08;
  504.     len_2       = 0x04;
  505.     callj_mask  = 0x40;
  506.   }
  507.  
  508.   for (natptr = native; count > 0; --count, ++natptr, ++generic) 
  509.   {
  510.     arelent *g = *generic;
  511.     unsigned char *raw = (unsigned char *)natptr;
  512.     asymbol *sym = *(g->sym_ptr_ptr);
  513.       
  514.     asection *output_section = sym->section->output_section;
  515.     bfd_h_put_32(abfd, g->address, raw);  
  516.     /* Find a type in the output format which matches the input howto - 
  517.      * at the moment we assume input format == output format FIXME!!
  518.      */
  519.     /* FIXME:  Need callj stuff here, and to check the howto entries to
  520.        be sure they are real for this architecture.  */
  521.     if (g->howto== &howto_reloc_callj) 
  522.     {
  523.       raw[7] = callj_mask + pcrel_mask + len_2;
  524.     }
  525.     else if (g->howto == &howto_reloc_pcrel24) 
  526.     {
  527.       raw[7] = pcrel_mask +len_2;
  528.     }
  529.     else {
  530.     raw[7] = len_2;
  531.       }
  532.     if (output_section == &bfd_abs_section) 
  533.     {
  534.       r_extern = 0;
  535.       r_idx = N_ABS;
  536.       r_addend += sym->value;
  537.     }
  538.     else if (output_section == &bfd_com_section 
  539.          || output_section == &bfd_und_section) 
  540.     {
  541.       /* Fill in symbol */
  542.       r_extern = 1;
  543.       r_idx =  stoi((*(g->sym_ptr_ptr))->flags);
  544.     }
  545.     else 
  546.     {
  547.       /* Just an ordinary section */
  548.       r_extern = 0;
  549.       r_idx  = output_section->target_index;      
  550.     }
  551.  
  552.     if (abfd->xvec->header_byteorder_big_p) {
  553.     raw[4] = (unsigned char) (r_idx >> 16);
  554.     raw[5] = (unsigned char) (r_idx >>  8);
  555.     raw[6] = (unsigned char) (r_idx     );
  556.       } else {
  557.       raw[6] = (unsigned char) (r_idx >> 16);
  558.       raw[5] = (unsigned char) (r_idx>>  8);
  559.       raw[4] = (unsigned char) (r_idx     );
  560.     }  
  561. if (r_extern)
  562.     raw[7] |= extern_mask; 
  563.   }
  564.  
  565.   if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
  566.       free((PTR)native);
  567.       return false;
  568.     }
  569.   free ((PTR)native);
  570.  
  571.   return true;
  572. }
  573.  
  574. /* This is stupid.  This function should be a boolean predicate */
  575. static unsigned int
  576. b_out_canonicalize_reloc (abfd, section, relptr, symbols)
  577.      bfd *abfd;
  578.      sec_ptr section;
  579.      arelent **relptr;
  580.      asymbol **symbols;
  581. {
  582.   arelent *tblptr = section->relocation;
  583.   unsigned int count = 0;
  584.  
  585.  if (!(tblptr || b_out_slurp_reloc_table (abfd, section, symbols))) return 0;
  586.   tblptr = section->relocation;
  587.  if (!tblptr) return 0;
  588.  
  589.   for (; count++ < section->reloc_count;)
  590.     *relptr++ = tblptr++;
  591.  
  592.   *relptr = 0;
  593.  
  594.   return section->reloc_count;
  595. }
  596.  
  597. static unsigned int
  598. b_out_get_reloc_upper_bound (abfd, asect)
  599.      bfd *abfd;
  600.      sec_ptr asect;
  601. {
  602.   if (bfd_get_format (abfd) != bfd_object) {
  603.     bfd_error = invalid_operation;
  604.     return 0;
  605.   }
  606.  
  607.   if (asect == obj_datasec (abfd))
  608.     return (sizeof (arelent *) *
  609.         ((exec_hdr(abfd)->a_drsize / sizeof (struct relocation_info))
  610.          +1));
  611.  
  612.   if (asect == obj_textsec (abfd))
  613.     return (sizeof (arelent *) *
  614.         ((exec_hdr(abfd)->a_trsize / sizeof (struct relocation_info))
  615.          +1));
  616.  
  617.   bfd_error = invalid_operation;
  618.   return 0;
  619. }
  620.  
  621. static boolean
  622. b_out_set_section_contents (abfd, section, location, offset, count)
  623.      bfd *abfd;
  624.      sec_ptr section;
  625.      unsigned char *location;
  626.      file_ptr offset;
  627.       int count;
  628. {
  629.  
  630.   if (abfd->output_has_begun == false) { /* set by bfd.c handler */
  631.     if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL) /*||
  632.         (obj_textsec (abfd)->_cooked_size == 0) || (obj_datasec (abfd)->_cooked_size == 0)*/) {
  633.       bfd_error = invalid_operation;
  634.       return false;
  635.     }
  636.  
  637.     obj_textsec (abfd)->filepos = sizeof(struct internal_exec);
  638.     obj_datasec(abfd)->filepos = obj_textsec(abfd)->filepos 
  639.                                  +  obj_textsec (abfd)->_raw_size;
  640.  
  641.   }
  642.   /* regardless, once we know what we're doing, we might as well get going */
  643.   bfd_seek (abfd, section->filepos + offset, SEEK_SET);
  644.  
  645.   if (count != 0) {
  646.     return (bfd_write ((PTR)location, 1, count, abfd) == count) ?true:false;
  647.   }
  648.   return true;
  649. }
  650.  
  651. static boolean
  652. b_out_set_arch_mach (abfd, arch, machine)
  653.      bfd *abfd;
  654.      enum bfd_architecture arch;
  655.      unsigned long machine;
  656. {
  657.   bfd_default_set_arch_mach(abfd, arch, machine);
  658.  
  659.   if (arch == bfd_arch_unknown)    /* Unknown machine arch is OK */
  660.     return true;
  661.   if (arch == bfd_arch_i960)    /* i960 default is OK */
  662.     switch (machine) {
  663.     case bfd_mach_i960_core:
  664.     case bfd_mach_i960_kb_sb:
  665.     case bfd_mach_i960_mc:
  666.     case bfd_mach_i960_xa:
  667.     case bfd_mach_i960_ca:
  668.     case bfd_mach_i960_ka_sa:
  669.     case 0:
  670.       return true;
  671.     default:
  672.       return false;
  673.     }
  674.  
  675.   return false;
  676. }
  677.  
  678. static int 
  679. DEFUN(b_out_sizeof_headers,(ignore_abfd, ignore),
  680.       bfd *ignore_abfd AND
  681.       boolean ignore)
  682. {
  683.   return sizeof(struct internal_exec);
  684. }
  685.  
  686.  
  687.  
  688.  
  689. /* Build the transfer vectors for Big and Little-Endian B.OUT files.  */
  690.  
  691. /* We don't have core files.  */
  692. #define    aout_32_core_file_failing_command _bfd_dummy_core_file_failing_command
  693. #define    aout_32_core_file_failing_signal _bfd_dummy_core_file_failing_signal
  694. #define    aout_32_core_file_matches_executable_p    \
  695.                 _bfd_dummy_core_file_matches_executable_p
  696.  
  697. /* We use BSD-Unix generic archive files.  */
  698. #define    aout_32_openr_next_archived_file    bfd_generic_openr_next_archived_file
  699. #define    aout_32_generic_stat_arch_elt    bfd_generic_stat_arch_elt
  700. #define    aout_32_slurp_armap        bfd_slurp_bsd_armap
  701. #define    aout_32_slurp_extended_name_table    bfd_true
  702. #define    aout_32_write_armap        bsd_write_armap
  703. #define    aout_32_truncate_arname        bfd_bsd_truncate_arname
  704.  
  705. /* We override these routines from the usual a.out file routines.  */
  706. #define    aout_32_canonicalize_reloc    b_out_canonicalize_reloc
  707. #define    aout_32_get_reloc_upper_bound    b_out_get_reloc_upper_bound
  708. #define    aout_32_set_section_contents    b_out_set_section_contents
  709. #define    aout_32_set_arch_mach        b_out_set_arch_mach
  710. #define    aout_32_sizeof_headers        b_out_sizeof_headers
  711.  
  712. #define aout_32_bfd_debug_info_start        bfd_void
  713. #define aout_32_bfd_debug_info_end        bfd_void
  714. #define aout_32_bfd_debug_info_accumulate    (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
  715.  
  716. #define aout_32_bfd_get_relocated_section_contents  bfd_generic_get_relocated_section_contents
  717. #define aout_32_bfd_relax_section                   bfd_generic_relax_section
  718. bfd_target b_out_vec_big_host =
  719. {
  720.   "b.out.big",            /* name */
  721.   bfd_target_aout_flavour,
  722.   false,            /* data byte order is little */
  723.   true,                /* hdr byte order is big */
  724.   (HAS_RELOC | EXEC_P |        /* object flags */
  725.    HAS_LINENO | HAS_DEBUG |
  726.    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT ),
  727.   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
  728.   ' ',                /* ar_pad_char */
  729.   16,                /* ar_max_namelen */
  730.      2,                /* minumum alignment power */
  731.  
  732. _do_getl64, _do_putl64,  _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
  733. _do_getb64, _do_putb64,  _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
  734.     {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */
  735.        bfd_generic_archive_p, _bfd_dummy_target},
  736.     {bfd_false, b_out_mkobject,    /* bfd_set_format */
  737.        _bfd_generic_mkarchive, bfd_false},
  738.     {bfd_false, b_out_write_object_contents,    /* bfd_write_contents */
  739.        _bfd_write_archive_contents, bfd_false},
  740.  
  741.   JUMP_TABLE(aout_32)
  742. };
  743.  
  744.  
  745. bfd_target b_out_vec_little_host =
  746. {
  747.   "b.out.little",        /* name */
  748.   bfd_target_aout_flavour,
  749.   false,            /* data byte order is little */
  750.   false,            /* header byte order is little */
  751.   (HAS_RELOC | EXEC_P |        /* object flags */
  752.    HAS_LINENO | HAS_DEBUG |
  753.    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT ),
  754.   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
  755.   ' ',                /* ar_pad_char */
  756.   16,                /* ar_max_namelen */
  757.      2,                /* minum align */
  758. _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
  759. _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* hdrs */
  760.      
  761.     {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */
  762.        bfd_generic_archive_p, _bfd_dummy_target},
  763.     {bfd_false, b_out_mkobject,    /* bfd_set_format */
  764.        _bfd_generic_mkarchive, bfd_false},
  765.     {bfd_false, b_out_write_object_contents,    /* bfd_write_contents */
  766.        _bfd_write_archive_contents, bfd_false},
  767.   JUMP_TABLE(aout_32)
  768. };
  769.